<?php

/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Gdata
 * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */

/**
 * @see Zend_Gdata
 */
require_once 'Zend/Gdata.php';

/**
 * @see Zend_Gdata_Finance_PortfolioEntry
 */
Zend_Loader::loadClass('Zend_Gdata_Finance_PortfolioEntry');

/**
 * @see Zend_Gdata_Finance_PortfolioFeed
 */
Zend_Loader::loadClass('Zend_Gdata_Finance_PortfolioFeed');

/**
 * @see Zend_Gdata_Finance_PortfolioEntry
 */
Zend_Loader::loadClass('Zend_Gdata_Finance_TransactionEntry');

/**
 * @see Zend_Gdata_Finance_PortfolioFeed
 */
Zend_Loader::loadClass('Zend_Gdata_Finance_TransactionFeed');

/**
 * @see Zend_Gdata_Finance_Extension_TransactionData
 */
Zend_Loader::loadClass('Zend_Gdata_Finance_Extension_TransactionData');

/**
 * @see Zend_Gdata_Finance_PositionFeed
 */
Zend_Loader::loadClass('Zend_Gdata_Finance_PositionFeed');

/**
 * @see Zend_Gdata_Finance_PositionEntry
 */
Zend_Loader::loadClass('Zend_Gdata_Finance_PositionEntry');

/**
 * @see Zend_Gdata_App_Entry
 */
Zend_Loader::loadClass('Zend_Gdata_App_Entry');

/**
 * Service class for interacting with the Google Finance data API
 * @link http://code.google.com/apis/finance/
 *
 * @category   Zend
 * @package    Zend_Gdata
 * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Gdata_Finance extends Zend_Gdata
{

	const FINANCE_LIST_FEED_URI = 'http://finance.google.com/finance/feeds/default/portfolios';
	const AUTH_SERVICE_NAME = 'finance';

	protected $_defaultPostUri = self::FINANCE_LIST_FEED_URI;
	protected $_rootNamespace = 'gf';
	protected $_rootElement = 'portfolioData';

	public static $namespaces = array(
        'gf' => 'http://schemas.google.com/finance/2007');

	/**
	 * Create Gdata_Finance object
	 *
	 * @param Zend_Http_Client $client (optional) The HTTP client to use when
	 *          when communicating with the Google servers.
	 * @param string $applicationId The identity of the app in the form of Company-AppName-Version
	 *
	 */
	public function __construct($client = null, $applicationId = 'Dchimento-MyAppBeta-1.0')
	{
		$this->registerPackage('Zend_Gdata_Finance');
		$this->registerPackage('Zend_Gdata_Finance_Extension');
		parent::__construct($client, $applicationId);
		$this->_httpClient->setParameterPost('service', self::AUTH_SERVICE_NAME);
	}

	/**
	 * Retreive feed object containing entries for the user's Porfolios.
	 *
	 * @param mixed $location The location for the feed, as a URL or Query
	 * @return Zend_Gdata_Finance_PortfolioFeed
	 */
	public function getPortfolioFeed($location = null)
	{
		if ($location === null) {
			$uri = self::FINANCE_LIST_FEED_URI;
		} else if ($location instanceof Zend_Gdata_Query) {
			$uri = $location->getQueryUrl();
		} else {
			$uri = $location;
		}
		return parent::getFeed($uri,'Zend_Gdata_Finance_PortfolioFeed');
	}

	/**
	 * Retreive feed object containing entries for the user's Porfolios.
	 *
	 * @param mixed $location The location for the feed, as a URL or Query
	 * @return Zend_Gdata_Finance_PortfolioFeed
	 */
	public function getTransactionFeed($location = null)
	{
		if ($location === null) {
			$uri = self::FINANCE_LIST_FEED_URI;
		} else if ($location instanceof Zend_Gdata_Query) {
			$uri = $location->getQueryUrl();
		} else {
			$uri = $location;
		}
		return parent::getFeed($uri,'Zend_Gdata_Finance_TransactionFeed');
	}

	/**
	 * Retreive feed object containing entries for the user's Porfolios.
	 *
	 * @param mixed $location The location for the feed, as a URL or Query
	 * @return Zend_Gdata_Finance_PositionFeed
	 */
	public function getPositionFeed($location = null)
	{
		if ($location instanceof Zend_Gdata_Query) {
			$uri = $location->getQueryUrl();
		} else {
			$uri = $location;
		}
		return parent::getFeed($uri,'Zend_Gdata_Finance_PositionFeed');
	}

	/**
	 * Adds a profolio
	 *
	 * @param string $name the name of the portfolio
	 * @param string $currencyCode the default ISO currency code
	 * @return Zend_Gdata_Finance_PortfolioEntry
	 */
	public function addPortfolio($name,$currencyCode)
	{
		if ( $name == null or $currencyCode == null)
		{
			throw new Exception("Need to have a name and the ISO currencyCode to create a portfolio
			($name,$currencyCode)");
		}
	 $newEntry = new Zend_Gdata_Finance_PortfolioEntry();
	 $newEntry->setTitle(new Zend_Gdata_App_Extension_Title($name));
	 $newEntry->setPortfolioData(new Zend_Gdata_Finance_Extension_PortfolioData($currencyCode));
	 try
	 {
	 	$retEntry=$this->insertEntry($newEntry,$_defaultPostUri);
	 }
	 catch (Zend_Gdata_App_HttpException $e )
	 {
	 	require_once 'Zend/Gdata/App/HttpException.php';
	 	$exception = new Zend_Gdata_App_HttpException('An error occured while trying to create new folio: '
	 	. $e->getResponse()->getBody()
	 	);
	 	$exception->setResponse($e->getResponse() );
	 	throw $exception;
	 }
	 return $retEntry;
	}

	/**
	 * Deletes a portfolio
	 *
	 * @param string $name the name of the portfolio to delete
	 * @return boolean
	 */
	public function delPortfolio($name)
	{
		$entry=$this->getPortfolio($name);
		if(isset($entry))
		return $entry->delete();
		return false;
	}

	/**
	 * Returns a porfolio entry by name
	 *
	 * @param string $name the name of the portfolio to delete
	 * @return Zend_Gdata_Finance_PortfolioEntry
	 */
	public function getPortfolio($name)
	{
		if ( $name == null)
		{
			throw new Exception("Need a name of portfolio to search");
		}
		$feed =$this->getPortfolioFeed();
		foreach ($feed as $feedEntry)
		{
			if ( $name == $feedEntry->getTitleValue() )
			return $feedEntry;
		}
		return null;
	}

	/**
	 * Adds a transaction to a portfolio
	 *
	 * @param Zend_Gdata_Finance_PortfolioEntry $portfolio The portfolio object to add a transaction
	 * @param string $type Type of transaction; "Buy","Sell"
	 * @param string $exchange The exchange where the stock is located (e.g. NYSE)
	 * @param string $stock The ticker symbol
	 * @param string $date Date in ISO format YYYY-MM-DDT00:00:00.000
	 * @param string $shares Number of shares
	 * @param string $notes Free text notes
	 * @param string $commission Commission fee
	 * @param string $price Price of stock
	 * @return boolean
	 */
	public function addTransaction(Zend_Gdata_Finance_PortfolioEntry $portfolio,$type,$exchange,$stock,
	$date=null,$shares=null,$notes=null,$commission=null,$price=null)
	{
		if(isset($portfolio))
		{
			$transac = new Zend_Gdata_Finance_TransactionEntry();
			$transacData = new Zend_Gdata_Finance_Extension_TransactionData();
			$transacData->setType($type);
			$transacData->setDate($date);
			$transacData->setShares($shares);
			$transacData->setNotes($notes);
			if ($commission != null)
			{
				$transacData->setCommission(new Zend_Gdata_Finance_Extension_Commission($commission,"USD"));
			}
			if ( $price != null)
			{
				$transacData->setPrice(new Zend_Gdata_Finance_Extension_Price($price,"USD"));
			}
			$transac->setTransactionData($transacData);
			try
			{
				$retEntry=$this->insertEntry($transac,$portfolio->getId() .
                 	      "/positions/" . "$exchange%3A$stock" . "/transactions");
			}
			catch (Zend_Gdata_App_HttpException $e )
			{
				require_once 'Zend/Gdata/App/HttpException.php';
				$exception = new Zend_Gdata_App_HttpException('An error occured while adding a transaction: '
				. $e->getResponse()->getBody()  );
				$exception->setResponse($e->getResponse() );
				throw $exception;
			}
		}
		return false;
	}
}
